﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZhCun.DBCommon;
using ZhCun.Utils.Helpers;

namespace ZhCun.WebCommon
{
    /// <summary>
    /// 解密过滤器
    /// </summary>
    public class BodyEncryptFilterAttribute : Attribute, IResourceFilter, IActionFilter
    {
        static BodyEncryptFilterAttribute()
        {
            _RSA = new RSAHelper(AppCommonConfig.AppSettings.RsaPrivateKey);
        }

        /// <summary>
        /// 加密Key
        /// </summary>
        private string AesKey;

        private bool IsEncrypt = false;

        private readonly static RSAHelper _RSA;

        public void OnResourceExecuting(ResourceExecutingContext context)
        {
            if (!(context.ActionDescriptor is ControllerActionDescriptor action))
            {
                IsEncrypt = false;
                return;
            }
            if (context.Filters.FirstOrDefault(s => s.GetType() == typeof(BodyEncryptFilterAttribute)) == null)
            {
                IsEncrypt = false;
                return;
            }
            //如果标记未加密
            if (action.MethodInfo.GetCustomAttributes(typeof(NonEncryptAttribute), false).Any())
            {
                IsEncrypt = false;
                return;
            }
            //使用rsa加密的aes key
            var aesEncryptKey = context.HttpContext.GetHeader(Constants.DATA_ENCRYPT_KEY_VALUE);
            if (string.IsNullOrWhiteSpace(aesEncryptKey))
            {
                IsEncrypt = false;
                if (AppCommonConfig.AppSettings.DataEncrypt)
                {
                    context.Result = new ObjectResult("data format error") { StatusCode = StatusCodes.Status400BadRequest };
                }
                //密钥为空不进行加解密
                return;
            }
            IsEncrypt = true;
            AesKey = _RSA.Decrypt(aesEncryptKey);
            //如果get请求而且配置了加密，那么请求内容不解密，返回内容进行加密
            if (context.HttpContext.Request.Method == "POST")
            {
                using (var buffer = new MemoryStream())
                {
                    context.HttpContext.Request.Body.CopyTo(buffer);
                    var bodyStr = System.Text.Encoding.UTF8.GetString(buffer.GetBuffer(), 0, (int)buffer.Length);
                    var bodyBytes = DEncryptAES.DecryptBytes(bodyStr, AesKey);
                    context.HttpContext.Request.Body = new MemoryStream(bodyBytes);


                    ////var aa = System.Text.Encoding.UTF8.GetBytes("{Name:'张存',Age:35,Pwd:'" + AesKey + "'}");
                    ////var newBody = new ReadableResponseBody(context.HttpContext.Response.Body);
                    //if (context.HttpContext.Response.Body is IReadableBody body)
                    //{
                    //    body.IsRead = true;
                    //}
                }
            }
        }

        public void OnActionExecuted(ActionExecutedContext context)
        {
            if (IsEncrypt)
            {
                if (context.Result is ObjectResult rObj && rObj.Value != null)
                {
                    var bodyStr = JsonConvert.SerializeObject(rObj.Value);
                    var enResult = DEncryptAES.Encrypt(bodyStr, AesKey);
                    rObj.Value = enResult;
                }
            }
        }

        public void OnActionExecuting(ActionExecutingContext context)
        {

        }

        public void OnResourceExecuted(ResourceExecutedContext context)
        { }
    }
}